逃避雖可恥,但有用。
但這句話恐怕在我身上行不通。
每一次當我遇到問題時,我只有兩種選擇:
這兩種選擇我都有試過,面對處理它這項選擇,往往結果好更甚於逃避,因為,逃了一次,還會再遇見N次... ...
當我從leetcode網站點選等級為easy的第一道程式後,我立刻浮現了以上選項,因為這題對我不簡單容易,但有鑑於過去大量失敗經歷,我只能面對問題。
以下是Two of the sum 部分內文
Example 1:
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].
Example 2:
Input: nums = [3,2,4], target = 6
Output: [1,2]
Example 3:
Input: nums = [3,3], target = 6
Output: [0,1]
Constraints:
2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
Only one valid answer exists.
我們從輸入與輸出範例可以曉得,輸入有陣列(整數,一大串整數)和單整數(陣列裡挑兩個加總的合),然後,我們必須找出是哪兩個數加總的,並輸出他們在陣列的第幾位。
好吧!因為我很久沒有打C++程式了,我一時之間只有腦袋空白。
然而,我卻記得平行運算的課程中,老師有提到暴力解以及時間複雜度。
如果是暴力解,就是寫出雙回圈,將輸入的陣列一一相加跟目標數值比對,就完成了。時間複雜度是O(n^2)
由於我想不出來更好的解法,所以我決定從網路撈出解答來分析:
class Solution {
public:
vector<int> twoSum(vector<int>&/*指標變數*/ nums, int target) {
map<int, int> mymap;//map 使用的是紅黑樹演算法,簡單來說,就是map自行安排順序,使搜尋更快速
vector<int> ans;
for(int i=0; i < nums.size(); i++){
if(mymap.find(nums[i]) != mymap.end()){ // 在的話就表示找到了,可以將結果取得,
ans.push_back(mymap[nums[i]]);
ans.push_back(i);
return ans;
}
else{
mymap[target - nums[i]] = i;//每一次從map中確認當下target-num是否在map中,
//沒找到的話,就將一組(num, index)放進map中,
}
}
return ans;
}
};
恩........我想我有待加強。所以到底為甚麼是target-num呢?如果從例子找問題 [2,7,11,15], target = 9
第一圈當i=0時,進入else, mymap[9-2=7]=0;也就是mymap[7]=0;
第二圈當i=1時,進入if, mymap.find(7)!=mymap.end();這是因為,find會尋找key,而我們在i=0時,存了key=7, 值=0的map,所以map裡是有以key為7的值。
mymap[nums[i]] =0, i=1, ans={0, 1}
也就是說,由於答案是a+b的情況下,我們可以將sum-a後的值作為key存起來,第幾迴圈i作為map值儲存。
若nums有值與sum-a一樣,也就是b,我們就將map的值與當下迴圈i存入ans vector。
如果不對,map會繼續存新的key和值,直到找到答案。
最後,因為只有單迴圈就能找到解,所以時間複雜度O(n)
我有點消化不良,也許之後再複習.......